package se.webbzon.oschi01.world;

import java.awt.geom.Point2D;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;

import se.webbzon.oschi01.region.RegionWriter;
import se.webbzon.oschi01.singleton.Singletons;
import se.webbzon.oschi01.utils.Progress;
import se.webbzon.oschi01.utils.Tunnel;

public class WorldFileWriter extends WorldWriter<File> {
	
	private final ProgressImpl progress;
	
	public WorldFileWriter() {
		progress = new ProgressImpl();
	}
	
	@Override public Progress<Object> getProgress() {
		return progress;
	}

	@Override public synchronized void write(World world, File file) throws IOException {
		if (file.isFile())
			file = file.getParentFile();
		
		RegionWriter regionWriter = Singletons.instance(RegionWriter.class);
		int dimensions = world.dimensions();
		for (int i = 0; i < dimensions; i++) {
			Dimension d = world.getDimension(i);
			
			// Create region directory
			File regionDirectory;
			if (isOverworld(d))
				regionDirectory = new File(file,"region");
			else
				regionDirectory = new File(file,d.getName() + "/region");
			if (!regionDirectory.exists())
				regionDirectory.mkdirs();
			
			int regions = d.regions();
			for (int j = 0; j < regions; j++) {
				Region r = d.getRegion(j);
				
				// Create region file
				Point2D p = r.getCoordinate();
				String filename = "r." + ((int) p.getX()) + "." + ((int) p.getY()) + ".mca";
				File regionFile = new File(regionDirectory,filename);
				if (regionFile.exists())
					regionFile.delete();
				regionFile.createNewFile();
				
				double pr = (i + j / (double) regions) / (double) dimensions;
				progress.setProgress((int) (90 * pr), "Writing to " + regionFile.getCanonicalPath());
				
				FileOutputStream fos = new FileOutputStream(regionFile);
				regionWriter.write(r, fos);
				fos.close();				
			}
			
		}
		
		Collection<String> data = world.getData();
		int n = data.size();
		int i = 0;
		for (String datum : world.getData()) {
			File datumFile = new File(file,datum);
			progress.setProgress(90 + (10 * i) / n, "Writing to " + datumFile.getCanonicalPath());
			if (datumFile.exists()) {
				datumFile.delete();
			} else {
				File datumDir = datumFile.getParentFile();
				if (!datumDir.exists())
					datumDir.mkdirs();
			}
			datumFile.createNewFile();
			FileOutputStream fos = new FileOutputStream(datumFile);
			Tunnel t = new Tunnel(fos);
			world.getDatum(datum, t);
			fos.close();
			i++;
		}
		progress.complete(null, "World writing complete!");
	}
	
	private boolean isOverworld(Dimension d) {
		return d.getName().isEmpty() || d.getName().equalsIgnoreCase("overworld");
	}
	
	private final class ProgressImpl extends Progress<Object> {

		@Override public void complete(Object result) {
			super.complete(result);
		}

		@Override public void abort(Exception e) {
			super.abort(e);
		}

		@Override public void setProgress(int progress) {
			super.setProgress(progress);
		}		
		
	}
}
